from django.core.management.base import BaseCommand
from django.db import transaction
from django.utils import timezone
from datetime import timedelta
from battles.models import Battle, BattleRound, BattleExecutionLog

"""
# 状态 ['error', 'pending', 'running', 'finished']

# 删除最早的100条战报
python manage.py cleanup_battles --limit 100

# 删除7天前的最早的50条战报
python manage.py cleanup_battles --days 7 --limit 50

# 删除最早的20条状态为error的战报
python manage.py cleanup_battles --limit 20 --status error

# 删除30天前的最早的100条战报（试运行）
python manage.py cleanup_battles --days 30 --limit 100 --dry-run

# 强制删除最早的10条战报，不包含相关数据
python manage.py cleanup_battles --limit 10 --force --no-include-related
"""

class Command(BaseCommand):
    help = '清理战报数据，包括相关的回放、回合和日志数据'

    def add_arguments(self, parser):
        parser.add_argument(
            '--days',
            type=int,
            help='删除多少天前的战报（与--limit参数可以组合使用）',
        )
        parser.add_argument(
            '--battle-id',
            type=int,
            help='删除指定ID的战报（无论状态如何）',
        )
        parser.add_argument(
            '--status',
            type=str,
            choices=['error', 'pending', 'running', 'finished'],
            help='要清理的战报状态（不指定则删除所有状态的战报）',
        )
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='仅显示将要删除的数据，不实际执行删除操作',
        )
        parser.add_argument(
            '--force',
            action='store_true',
            help='强制删除，跳过确认步骤',
        )
        parser.add_argument(
            '--include-related',
            action='store_true',
            help='同时删除相关的回放、回合和日志数据（默认启用）',
        )
        parser.add_argument(
            '--limit',
            type=int,
            help='限制删除的战报数量（按创建时间从旧到新排序）',
        )

    def handle(self, *args, **options):
        days = options['days']
        battle_id = options.get('battle_id')
        status = options['status']
        dry_run = options['dry_run']
        force = options['force']
        include_related = options.get('include_related', True)
        limit = options.get('limit')

        # 参数验证
        if not battle_id and not days and not limit:
            self.stdout.write(
                self.style.ERROR('必须指定以下参数之一：--days, --limit, 或 --battle-id')
            )
            return

        # 获取需要删除的战报
        if battle_id:
            battles = Battle.objects.filter(id=battle_id)
            if not battles.exists():
                self.stdout.write(
                    self.style.ERROR(f'未找到ID为{battle_id}的战报')
                )
                return
            self.stdout.write(f'准备删除指定的战报 ID: {battle_id}')
        else:
            # 构建查询条件
            query_filters = {}

            # 如果指定了天数，添加时间过滤
            if days:
                cutoff_date = timezone.now() - timedelta(days=days)
                query_filters['created_at__lt'] = cutoff_date

            # 如果指定了状态，添加状态过滤
            if status:
                query_filters['status'] = status
                status_desc = f'状态为"{status}"的'
            else:
                status_desc = '所有状态的'

            # 构建查询集，按创建时间排序（从旧到新）
            battles_query = Battle.objects.filter(**query_filters).order_by('created_at')
            
            # 如果指定了限制数量，先获取ID列表
            if limit:
                battle_ids = list(battles_query.values_list('id', flat=True)[:limit])
                battles = Battle.objects.filter(id__in=battle_ids)
                limit_desc = f'前{limit}条'
            else:
                battles = battles_query
                limit_desc = ''

            if battles.count() == 0:
                time_desc = f'{days}天前' if days else ''
                self.stdout.write(
                    self.style.WARNING(f'没有找到{time_desc}{status_desc}{limit_desc}战报')
                )
                return

        # 统计相关数据
        battle_count = battles.count()

        if include_related:
            round_count = BattleRound.objects.filter(battle__in=battles).count()
            log_count = BattleExecutionLog.objects.filter(battle__in=battles).count()
        else:
            round_count = log_count = 0

        # 显示统计信息
        self.stdout.write('\n' + '='*50)
        self.stdout.write('删除统计信息:')
        self.stdout.write(f'  战报数量: {battle_count}')
        if include_related:
            self.stdout.write(f'  回合数据: {round_count}')
            self.stdout.write(f'  执行日志: {log_count}')
        self.stdout.write('='*50 + '\n')

        if dry_run:
            self.stdout.write(self.style.WARNING('这是一次试运行，不会实际删除数据'))

            # 显示最近的10个将要删除的战报详情（按创建时间倒序）
            sample_battles = battles.order_by('-created_at')[:10]
            self.stdout.write('\n最近的10个将要删除的战报:')
            for battle in sample_battles:
                self.stdout.write(
                    f'  ID: {battle.id}, '
                    f'状态: {battle.get_status_display()}, '
                    f'创建时间: {battle.created_at.strftime("%Y-%m-%d %H:%M:%S")}, '
                    f'玩家: {battle.player1.username} vs {battle.player2.username}'
                )

            if battle_count > 10:
                self.stdout.write(f'  ... 还有 {battle_count - 10} 个战报')

            return

        # 确认删除操作
        if not force:
            time_desc = f'{days}天前' if days else ''
            status_desc = f'状态为"{status}"的' if status else '所有状态的'
            limit_desc = f'前{limit}条' if limit else ''
            confirm = input(f'\n确定要删除 {battle_count} 个{time_desc}{status_desc}{limit_desc}战报吗？(y/N): ')
            if confirm.lower() != 'y':
                self.stdout.write('操作已取消')
                return

        # 执行删除操作
        try:
            with transaction.atomic():
                deleted_counts = {'battles': 0, 'replays': 0, 'rounds': 0, 'logs': 0}

                if include_related:
                    # 删除相关数据
                    self.stdout.write('正在删除相关数据...')

                    # 删除执行日志
                    if log_count > 0:
                        deleted_logs = BattleExecutionLog.objects.filter(battle__in=battles).delete()
                        deleted_counts['logs'] = deleted_logs[0]
                        self.stdout.write(f'  已删除 {deleted_counts["logs"]} 条执行日志')

                    # 删除回合数据
                    if round_count > 0:
                        deleted_rounds = BattleRound.objects.filter(battle__in=battles).delete()
                        deleted_counts['rounds'] = deleted_rounds[0]
                        self.stdout.write(f'  已删除 {deleted_counts["rounds"]} 个回合数据')



                # 删除战报
                self.stdout.write('正在删除战报...')
                deleted_battles = battles.delete()
                deleted_counts['battles'] = deleted_battles[0]

                # 显示删除结果
                self.stdout.write('\n' + '='*50)
                self.stdout.write(self.style.SUCCESS('删除操作完成！'))
                self.stdout.write(f'实际删除的数据:')
                self.stdout.write(f'  战报: {deleted_counts["battles"]}')
                if include_related:
                    self.stdout.write(f'  回合数据: {deleted_counts["rounds"]}')
                    self.stdout.write(f'  执行日志: {deleted_counts["logs"]}')
                self.stdout.write('='*50)

        except Exception as e:
            self.stdout.write(
                self.style.ERROR(f'删除操作失败: {e}')
            )
            raise

    def _format_battle_info(self, battle):
        """格式化战报信息用于显示"""
        return (
            f'ID: {battle.id}, '
            f'状态: {battle.get_status_display()}, '
            f'结果: {battle.get_result_display() if battle.result else "无"}, '
            f'创建时间: {battle.created_at.strftime("%Y-%m-%d %H:%M:%S")}, '
            f'玩家: {battle.player1.username} vs {battle.player2.username}'
        )